﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.SessionState;
using Common;
using Controllers.Controllers;
using Newtonsoft.Json.Serialization;
using QScheduler;


namespace UI
{
    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明，
    // 请访问 http://go.microsoft.com/?LinkId=9394801

    //在 Global.asax 被更改后ASP.NET 页面框架会重新启动应用程序，包括关闭所有的浏览器会话，去除所有状态信息，并重新启动应用程序域。
    //程序在刚启动时，会执行一次Global.asax   
    public class MvcApplication : System.Web.HttpApplication
    {

        protected void Application_Start()
        {
            //初始化视图引擎为Razor视图引擎
            //规定了系统只能采用Razor视图引擎，省去了判断选择视图引擎的过程，属于视图引擎的优化
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new RazorViewEngine());

            AreaRegistration.RegisterAllAreas();
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Disabled); //全局禁用session

            WebApiConfig.Register(GlobalConfiguration.Configuration);//禁webapi,dll暂时没有引用，外加没有api的功能
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); //注册全局过滤器（对每次请求进行过滤）
            RouteConfig.RegisterRoutes(RouteTable.Routes); //注册路由规则
            IocConfig.BuildMvcContainer();//Ioc注入


            // 使webapi默认返回为json 
            //GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
            //GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver { IgnoreSerializableAttribute = true };

            //调度程序
            QuartzBll.Start();
            //FluentBll.Start();




            Debug.WriteLine(
                "*********************************Application_Start执行完毕****************************************");
        }

        protected void Application_End()
        {
            QuartzBll.Stop();
        }

        /// <summary>
        /// 顶层统一异常日志处理和异常页面反馈(这是异常的最顶层控制,能处理500以外的错误，开发版使用，帮助找错)
        /// </summary>
        protected void Application_Error(object sender, EventArgs e)
        {
            Exception ex = HttpContext.Current.Server.GetLastError();
            HttpContext httpContext = ((MvcApplication)sender).Context;
            RouteData currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
            ErrorController errorController = new ErrorController();
            RouteData jumpRouteData = new RouteData();
            string currentController = "";
            string currentAction = "";
            string jumpAction = "Error";

            #region 跳转异常页前先记录异常

            Type exceptionType = typeof(Exception);
            if (ex.GetType() == exceptionType)//异常可能被Throw new Exception(e.Message);处理过
            {
                LogHelper.WriteErrorLog(exceptionType, ex, "异常可能被程序捕获处理(*^__^*)");
            }
            else
            {
                LogHelper.WriteErrorLog(ex.GetType(), ex, "异常未被程序捕获处理(●￣(ｴ)￣●)");
            }

            #endregion

            #region 跳转异常页面

            if (!new HttpRequestWrapper(httpContext.Request).IsAjaxRequest()) //非ajax异步请求页面控制跳转，ajax请求直接由ajax的error方法输出异常
            {
                if (currentRouteData != null)
                {
                    if (currentRouteData.Values["controller"] != null && !string.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
                    {
                        currentController = currentRouteData.Values["controller"].ToString();
                    }
                    if (currentRouteData.Values["action"] != null && !string.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
                    {
                        currentAction = currentRouteData.Values["action"].ToString();
                    }
                }
                if (ex is HttpException)
                {
                    var httpEx = ex as HttpException;
                    switch (httpEx.GetHttpCode())
                    {
                        case 404://500以外错误
                            {
                                jumpAction = "Page404";
                                break;
                            }
                        default://500错误
                            {
                                jumpAction = "Error";
                                break;
                            }
                    }
                }
                httpContext.ClearError();
                httpContext.Response.Clear();
                httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
                httpContext.Response.TrySkipIisCustomErrors = true;
                jumpRouteData.Values["controller"] = "Error";
                jumpRouteData.Values["action"] = jumpAction;
                if (jumpAction == "Page404")//如果访问的控制器不存在则会显示404页面源码，此处为修复此Bug单独处理404错误
                {
                    Response.Redirect("/Error/Page404");
                }
                else
                {
                    errorController.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);//错误信息
                    ((IController)errorController).Execute(//请求转发
                        new RequestContext(
                            new HttpContextWrapper(httpContext), //类似于请求转发（始终是一次请求）
                            jumpRouteData)
                        );
                }
            }    

            #endregion

        }
    }
}